/*
 * $Id: ClientDrvHeartBeat.java,v 1.7 2009/06/02 17:32:12 afaichun Exp $
 * 
 * Copyright (C) 2006 General Electric Company. All Rights Reserved.
 * 
 * This software is the confidential and proprietary information of the General
 * Electric Company (GE). You shall not disclose this software and shall use it
 * only in accordance with the terms of the license agreement you entered into
 * with GE.
 * 
 * GE MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF THE
 * SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR
 * NON-INFRINGEMENT. GE SHALL NOT BE LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE
 * AS A RESULT OF USING, MODIFYING, OR DISTRIBUTING THIS SOFTWARE OR ITS
 * DERIVATIVES.
 */
package com.ge.healthcare.autosc.processor.iip.comm;

import java.util.Date;

import com.ge.healthcare.autosc.common.ASCLogger;
import com.ge.healthcare.autosc.common.ASCUtil;
import com.ge.healthcare.autosc.common.util.ApplicationInfo;
import com.ge.healthcare.autosc.common.util.PropertyConstants;
import com.ge.healthcare.autosc.processor.exception.ClientDrvCommandException;

/**
 * The class sends display command to clientdrv so that the communication
 * doesn't drops when we are doing heavy operations
 * @author 212042764
 * 
 */
public class ClientDrvHeartBeat extends Thread {

	private ClientDrvCommand clientDrvCmd = null;
	private String threadName = null;
	private long clientDrvPingDuration = ApplicationInfo.getInstance()
			.getIntegerPropertyValue(
					PropertyConstants.CLIENTDRV_PING_TIME_IN_SEC, "30") * 1000;
	private boolean heartBeat = false;
	private boolean skipFirstBeat = false;

	public ClientDrvHeartBeat(ClientDrvCommand rexecCmd, String threadName) {
		if (ASCUtil.isNullOrEmptyObject(rexecCmd) || !rexecCmd.isConnected()) {
			return;
		}
		this.clientDrvCmd = rexecCmd;
		this.threadName = threadName;
		heartBeat = true;
	}

	public ClientDrvHeartBeat(ClientDrvCommand rexecCmd, String threadName,
			boolean skipFirstBeat) {
		this(rexecCmd, threadName);
		this.skipFirstBeat = skipFirstBeat;
	}

	public void run() {
		String methodName = "run";
		// the "display" part is a command to the clientdrv -- do not change!
		String stillTicking = threadName
				+ " processing continues, please standby... ";
		do {
			String command = stillTicking + new Date();
			try {
				if (skipFirstBeat) {
					skipFirstBeat = false;
				}else {
					clientDrvCmd.executeHearbeatCommand(command);
				}
				Thread.sleep(clientDrvPingDuration);
			} catch (ClientDrvCommandException rexecException) {
				ASCLogger.error(this.getClass(), methodName,
						"Failed to execute heartbeat command: display " + command,
						rexecException);
				this.done();
			} catch (InterruptedException interruptedException) {
				ASCLogger.error(this.getClass(), methodName,
						"Failed to sleep for clientdrv heartbeat command:"
								+ command, interruptedException);
				// Thread requirement to be caught
				this.done();
			}
		} while (heartBeat);
		ASCLogger.info("Heart beat is done");
	}

	/**
	 * Stops the heartbeat
	 */
	public void done() {
		heartBeat = false;
	}

	/**
	 * Checks if it is beatable or not
	 * @return
	 */
	public boolean isBeatable() {
		return heartBeat;
	}
}
